<template>
  <el-card class="test-field">
    <!-- 自定义组件测试框, 用户自己配置 -->
    <el-form
      v-if="checkProp.length > 0"
      ref="checkForm"
      :model="formData"
      :rules="formRules"
      class="test-field-inner"
      label-suffix=" : "
    >
      <el-form-item
        class="test-field-item"
        :prop="checkProp"
        :label="checkLabel"
        label-position="right"
      >
        <component
          class="i-component"
          :is="renderComponent"
          v-model="formData[checkProp]"
          @change="onCheckForm"
        >
          <template v-if="renderComponent.includes('select')">
            <el-option
              v-for="item of checkSourceData"
              :key="item.value"
              :value="item.value"
              :label="item.label"
            />
          </template>
        </component>
        <slot></slot>
      </el-form-item>
    </el-form>
    <div class="test-examples" v-show="tData.length > 0">
      <header class="tip-tag">
        <el-tag>案例表格</el-tag>
      </header>
      <el-table :data="tData" :border="tableBorder" max-height="300">
        <!-- index -->
        <el-table-column width="66" type="index" align="center" />
        <!-- for-in-tColumms -->
        <el-table-column
          v-for="(col, colIdx) in tColumns"
          :key="`${colIdx + 1} ${col.prop}`"
          :prop="col.prop"
          :label="col.label"
          :width="col.width"
        >
          <template v-slot="{ row }">
            <!-- <span v-if="col.prop === 'isValid'">
              {{
                row[col.prop]
                  ? $t("COMMON.CheckSuccess")
                  : $t("COMMON.CheckFail")
              }}
            </span>  v-else -->
            <span>{{ row[col.prop] }}</span>
          </template>
        </el-table-column>
      </el-table>
    </div>
  </el-card>
</template>

<script>
function createCallback({
  prop,
  required = true,
  trigger = "",
  validator = (rule, value, callback) => {
    callback();
  },
}) {
  if (Array.isArray(validator)) {
    return {
      [prop]: validator.map((v) => ({
        required,
        ...(trigger.length ? { trigger } : {}),
        validator: v,
      })),
    };
  } else
    return {
      [prop]: {
        required,
        ...(trigger.length ? {} : {}),
        validator,
      },
    };
}

export default {
  name: "TestField",
  props: {
    /** checkComponent */
    checkComponent: {
      type: String,
      default: "input",
      validator(val) {
        const components = ["input", "select"];
        return components.includes(val.toLowerCase());
      },
    },
    checkSourceData: {
      type: Array,
      default() {
        return [];
      },
    },
    /**
     * 需要校验的属性
     */
    checkProp: {
      type: String,
      default: "",
    },
    /**
     * 需要校验的属性对应的标签
     */
    checkLabel: {
      type: String,
      default: "",
    },
    /**
     * 校验规则回调
     * 类型可能为单个校验函数或者校验函数集合
     */
    checkCallback: {
      type: [Function, Array],
      default: (r, val, cb) => {
        if (!val) {
          cb(new Error("check fail"));
        }
        cb();
      },
    },
    /** 表格是否需要宽高 */
    tableBorder: {
      type: Boolean,
      default: true,
    },
    /** 测试数据 */
    tData: {
      type: Array,
      default() {
        return [];
      },
    },
  },
  data() {
    const checkProp = this.checkProp;

    return {
      tColumns: [
        {
          label: "案例名称",
          prop: "caseName",
          width: "200",
        },
        {
          label: "示例",
          prop: "caseExample",
        },
        // {
        //   label: "校验结果",
        //   prop: "isValid",
        // },
      ],
      formData: {
        [checkProp]: "",
      },
    };
  },
  computed: {
    renderComponent() {
      const origin = this.checkComponent.toLowerCase();

      return `el-${origin}`;
    },
    formRules() {
      const { checkProp, checkCallback } = this;

      return createCallback({
        prop: checkProp,
        validator: checkCallback,
      });
    },
    checkForm() {
      const { checkForm } = this.$refs;
      return checkForm;
    },
  },
  mounted() {
    this.checkForm.clearValidate();
  },
  methods: {
    onCheckForm() {
      this.checkForm.validate((valid) => {
        console.log(valid);
      });
    },
  },
};
</script>

<style lang="scss" scoped>
.test-field {
  margin: 10px 0;

  .test-field-inner {
    width: 100%;

    .test-field-item {
      .i-component {
        display: inline-block;
        width: 270px;
      }

      // ::v-deep .el-form-item__error {
      //   position: absolute;
      //   left: 33.33%;
      // }
    }
  }

  .test-examples {
    .tip-tag {
      padding: 8px 0;
    }
  }
}
</style>
